package com.vk.work2pdfdemo.utils;

import com.vk.work2pdfdemo.entity.Enterprises;
import com.vk.work2pdfdemo.entity.Levy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Yin
 * 2024/02/08
 */
@Slf4j
public class ExcelCreateContract {

    public Map<String, Object> excelInput(MultipartFile file) {
        // 获取excel文件名
        String excelFileName = file.getOriginalFilename();
        if (excelFileName == null) {
            log.error("文件名称不能为空");
            return null;
        }
        int excelVersion = getExcelVersion(excelFileName);
        Workbook workbook = null;
        List<Enterprises> enterprisesList = new ArrayList<>();
        Levy levy = new Levy();

        // 2003版本xls
        if (excelVersion == 1) {
            try {
                workbook = new HSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                log.error("获取Excel对象失败", e);
            }
        }
        // 2007版本xlsx
        else if (excelVersion == 2) {
            try {
                workbook = new XSSFWorkbook(file.getInputStream());
            } catch (IOException e) {
                log.error("获取Excel对象失败", e);
            }
        }

        if (workbook != null) {
            enterprisesList = readContractTemplates(workbook);
            levy = readLevy(workbook);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("ContractTemplates", enterprisesList);
        map.put("Levy", levy);
        return map;
    }

    /**
     * 判断要导入的excel信息，0代表未接收到，1代表2003版，2代表2007版
     *
     * @param excelFileName 文件原始名称
     * @return int
     */
    private int getExcelVersion(String excelFileName) {
        int flag = 0;
        if (excelFileName.matches("^.+\\.(?i)(xls)$")) {
            flag = 1;
        } else if (excelFileName.matches("^.+\\.(?i)(xlsx)$")) {
            flag = 2;
        }
        return flag;
    }

    /**
     * 读取客户数据，将其放入对应的实体对象中
     *
     * @param workbook Excel对象
     * @return {@link List}<{@link Enterprises}>
     */
    private List<Enterprises> readContractTemplates(Workbook workbook) {
        List<Enterprises> enterprisesList = new ArrayList<>();

        // 获取第一张表
        Sheet sheet = workbook.getSheetAt(0);
        // 得到表的总行数
        int totalRows = sheet.getPhysicalNumberOfRows();
        int totalCells = 0;

        // 根据第一行（标题行）获得总列数，获得总列数得根据某行确定
        if (totalRows >= 1 && sheet.getRow(0) != null) {
            totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
        }

        // 逐行取数据，每行对应一条实体对象信息
        for (int rowNum = 1; rowNum < totalRows; rowNum++) {
            Row row = sheet.getRow(rowNum);
            if (row == null) {
                continue;
            }
            Enterprises enterprises = new Enterprises();

            // 逐列取数据，每列对应一个实体对象属性
            for (int colNum = 0; colNum < totalCells; colNum++) {
                Cell cell = row.getCell(colNum);
                if (cell != null) {
                    switch (colNum) {
                        case 0:
                            enterprises.setEnterpriseName(getStringCellValue(cell));
                            break;
                        case 1:
                            enterprises.setActualOfficeAddress(getStringCellValue(cell));
                            break;
                        case 2:
                            enterprises.setEnterpriseServeFee(getStringCellValue(cell));
                            break;
                        case 3:
                            enterprises.setBillCategoryNameA(getStringCellValue(cell));
                            break;
                        case 4:
                            enterprises.setBillCategoryNameB(getStringCellValue(cell));
                            break;
                        case 5:
                            enterprises.setAccountName(getStringCellValue(cell));
                            break;
                        case 6:
                            enterprises.setBankAccountName(getStringCellValue(cell));
                            break;
                        case 7:
                            enterprises.setAccountNumber(getStringCellValue(cell));
                            break;
                        case 8:
                            enterprises.setAccountTax(getStringCellValue(cell));
                            break;
                        case 9:
                            enterprises.setAccountPhone(getStringCellValue(cell));
                            break;
                        case 10:
                            enterprises.setAddress(getStringCellValue(cell));
                            break;
                        case 11:
                            enterprises.setProjectBackground(getStringCellValue(cell));
                            break;
                        case 12:
                            enterprises.setBusinessProcesses(getStringCellValue(cell));
                            break;
                        case 13:
                            enterprises.setContactorName(getStringCellValue(cell));
                            break;
                        case 14:
                            enterprises.setContactorMobile(getStringCellValue(cell));
                            break;
                        case 15:
                            enterprises.setDate(getStringCellValue(cell));
                            break;
                        default:
                            // handle default case
                            break;
                    }
                }
            }
            enterprisesList.add(enterprises);
        }

        return enterprisesList;
    }

    /**
     * 读服务商数据
     *
     * @param workbook Excel对象
     * @return {@link Levy}
     */
    private Levy readLevy(Workbook workbook) {
        Levy levy = new Levy();
        // 获取第二张表
        Sheet sheet = workbook.getSheetAt(1);
        // 得到表的总行数
        int totalRows = sheet.getPhysicalNumberOfRows();
        int totalCells = 0;

        // 根据第一行（标题行）获得总列数，获得总列数得根据某行确定
        if (totalRows >= 1 && sheet.getRow(0) != null) {
            totalCells = sheet.getRow(0).getPhysicalNumberOfCells();
        }

        // 逐行取数据，每行对应一条实体对象信息
        for (int rowNum = 1; rowNum < totalRows; rowNum++) {
            Row row = sheet.getRow(rowNum);
            if (row == null) {
                continue;
            }

            // 逐列取数据，每列对应一个实体对象属性
            for (int colNum = 0; colNum < totalCells; colNum++) {
                Cell cell = row.getCell(colNum);
                if (cell != null) {
                    switch (colNum) {
                        case 0:
                            levy.setLevyName(getStringCellValue(cell));
                            break;
                        case 1:
                            levy.setLevyContactorName(getStringCellValue(cell));
                            break;
                        case 2:
                            levy.setLevyContactorMobile(getStringCellValue(cell));
                            break;
                        case 3:
                            levy.setLevyContactorMail(getStringCellValue(cell));
                            break;
                        case 4:
                            levy.setLevyAddress(getStringCellValue(cell));
                            break;
                        case 5:
                            levy.setServiceType(getStringCellValue(cell));
                            break;
                        case 6:
                            levy.setLevyBankAccountName(getStringCellValue(cell));
                            break;
                        case 7:
                            levy.setLevyAccountNumber(getStringCellValue(cell));
                            break;
                        default:
                            // handle default case
                            break;
                    }
                }
            }
        }
        return levy;
    }

    // 辅助方法，用于获取单元格的字符串值
    private String getStringCellValue(Cell cell) {
        if (cell.getCellTypeEnum() != CellType.STRING) {
            cell.setCellType(CellType.STRING);
        }
        return cell.getStringCellValue();
    }
}